
#import "RTFDescription.h"

static const char *header = "{\\rtf0\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\fo\n";

@implementation RTFDescription

- init
{
	[super init];
	textStream = NULL;
	buffer = NULL;
	return self;
}
	
- free
{
	if(textStream)
		NXCloseMemory(textStream,NX_FREEBUFFER);
	NX_FREE(buffer);
	return [super free];
}

- copyFromZone:(NXZone *)zone
{
	RTFDescription *theCopy;
	
	theCopy = [super copyFromZone:zone];
	theCopy->textStream = NULL;
	if(buffer){
		NX_ZONEMALLOC(zone, theCopy->buffer,char,strlen(buffer) + 1);
		strcpy(theCopy->buffer, buffer);
	} else
		theCopy->buffer = NULL;
	return theCopy;
}
	
- (NXStream *)stream
{
	if(!textStream){
		textStream = NXOpenMemory(0,0,NX_READWRITE);
		if(!buffer)
			NXWrite(textStream, header, strlen(header));
		else
			NXWrite(textStream, buffer, strlen(buffer));
	}
	NXSeek(textStream, 0L, NX_FROMSTART);
	return textStream;
}

- freeStream
{
	if(textStream)
		NXCloseMemory(textStream,NX_FREEBUFFER);
	textStream = NULL;
	return self;
}

- setRTFFromTextView:aView
{
	int maxlen,length;
	char *ptr;
	
	if(textStream)
		NXCloseMemory(textStream,NX_FREEBUFFER);
	textStream = NXOpenMemory(0,0,NX_READWRITE);
	[aView writeRichText:textStream];
	NXGetMemoryBuffer(textStream, &ptr, &length, &maxlen);
	if(buffer){
		NX_ZONEREALLOC([self zone], buffer,char,length + 1);	
	} else {
		NX_ZONEMALLOC([self zone], buffer,char,length + 1);
	}
	strcpy(buffer,ptr);
	NXCloseMemory(textStream,NX_FREEBUFFER);
	textStream = NULL;
	return self;
}
	
- setRTF:(const char *)string
{
	if(buffer){
		NX_ZONEREALLOC([self zone], buffer,char,strlen(string) + 1);	
	} else {
		NX_ZONEMALLOC([self zone], buffer,char,strlen(string) + 1);
	}
	strcpy(buffer, string);
	return self;
}
	
- setAscii:(const char *)string
{
	int maxlen,length;
	char *ptr;
	
	if(!string){
		NX_FREE(buffer);
		buffer = NULL;
		return self;
	}
	if(textStream)
		NXCloseMemory(textStream,NX_FREEBUFFER);
	textStream = NXOpenMemory(0,0,NX_READWRITE);
	NXWrite(textStream, header, strlen(header));
	NXSeek(textStream, 0L, NX_FROMEND);
	while(*string){
		switch(*string){
			case '\n':
			case '{':
			case '}':
			case '\\':
				NXPutc(textStream, '\\');
			break;
			default:
			break;
		}
		NXPutc(textStream, *string);
		string++;
	}
	NXGetMemoryBuffer(textStream, &ptr, &length, &maxlen);
	if(buffer){
		NX_ZONEREALLOC([self zone], buffer,char,length + 1);	
	} else {
		NX_ZONEMALLOC([self zone], buffer,char,length + 1);
	}
	strcpy(buffer,ptr);
	NXCloseMemory(textStream,NX_FREEBUFFER);
	textStream = NULL;
	return self;
}
	
- beginAppend
{
	if(textStream)
		NXCloseMemory(textStream,NX_FREEBUFFER);
	textStream = NXOpenMemory(0,0,NX_READWRITE);
	NXWrite(textStream, header, strlen(header));
	return self;
}

- appendRTF:(const char *)string
{
	if(!string)
		return self;
	NXSeek(textStream, 0L, NX_FROMEND);
	NXWrite(textStream, string, strlen(string));
	return self;
}

- appendAscii:(const char *)string
{
	if(!string)
		return self;
	NXSeek(textStream, 0L, NX_FROMEND);
	while(*string){
		switch(*string){
			case '\n':
			case '{':
			case '}':
			case '\\':
				NXPutc(textStream, '\\');
			break;
			default:
			break;
		}
		NXPutc(textStream, *string);
		string++;
	}
	return self;
}

- bold:(BOOL)flag
{
	[self appendRTF: flag ? "\\b " : "\\b0 "];
	return self;
}

- setJustify:(int)mode
{
	switch(mode){
		case NX_LEFTALIGNED:
		case NX_JUSTIFIED:
			[self appendRTF:"\\ql "];
			break;
		case NX_CENTERED:
			[self appendRTF:"\\qc "];
			break;
		case NX_RIGHTALIGNED:
			[self appendRTF:"\\qr "];
			break;
		default:
			break;
	}
	return self;
}

- endAppend
{
	int maxlen,length;
	char *ptr;
	
	NXGetMemoryBuffer(textStream, &ptr, &length, &maxlen);
	if(buffer){
		NX_ZONEREALLOC([self zone], buffer,char,length + 1);	
	} else {
		NX_ZONEMALLOC([self zone], buffer,char,length + 1);
	}
	strcpy(buffer,ptr);
	NXCloseMemory(textStream,NX_FREEBUFFER);
	textStream = NULL;
	return self;
}

- write:(NXTypedStream *)stream
{
	NXWriteType(stream,"*",&buffer);
	return self;
}

- read:(NXTypedStream *)stream
{
	NXReadType(stream,"*",&buffer);
	return self;
}

- awake
{
	[super awake];
	textStream = NULL;
	return self;
}

@end

 